// Global singleton audio service

let audioElement = null
let isInitialized = false

function ensureElement() {
  if (!audioElement) {
    audioElement = new Audio()
    audioElement.preload = 'auto'
  }
  return audioElement
}

/**
 * Initialize the audio with a source URL. Loads immediately.
 * @param {string} src
 * @param {{ loop?: boolean, volume?: number }} [options]
 */
function init(src, options = {}) {
  const el = ensureElement()
  if (typeof src === 'string' && src.length > 0) {
    if (el.src !== src) el.src = src
  }
  if (typeof options.loop === 'boolean') el.loop = options.loop
  if (typeof options.volume === 'number') el.volume = Math.min(1, Math.max(0, options.volume))
  try { el.load() } catch (_) {}
  isInitialized = true
}

/**
 * Play audio (returns a promise; may require user gesture on some browsers)
 * @returns {Promise<void>}
 */
async function play() {
  const el = ensureElement()
  try {
    await el.play()
  } catch (err) {
    // Autoplay blocked; caller can retry after a user gesture
    throw err
  }
}

/** Pause audio */
function pause() {
  const el = ensureElement()
  try { el.pause() } catch (_) {}
}

/** Toggle play/pause */
async function toggle() {
  const el = ensureElement()
  if (el.paused) return play()
  pause()
}

/**
 * Update source (will load but not auto-play by default)
 * @param {string} src
 */
function setSrc(src) {
  const el = ensureElement()
  if (typeof src === 'string' && src.length > 0) {
    if (el.src !== src) el.src = src
    try { el.load() } catch (_) {}
  }
}

/** Set volume between 0 and 1 */
function setVolume(volume) {
  const el = ensureElement()
  el.volume = Math.min(1, Math.max(0, Number(volume)))
}

/** Enable/disable loop */
function setLoop(loop) {
  const el = ensureElement()
  el.loop = Boolean(loop)
}

/** Whether audio is currently playing */
function isPlaying() {
  const el = ensureElement()
  return !el.paused && !el.ended
}

export default {
  init,
  play,
  pause,
  toggle,
  setSrc,
  setVolume,
  setLoop,
  isPlaying,
  get element() { return ensureElement() },
  get initialized() { return isInitialized },
}


